package com.young.scrollchildanim;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ScrollView;

/**
 * Author：young
 * .
 * Time： 2022/5/7 11:16 周六
 * .
 * Desc：挂载动画的滚动视图
 */
public class MountAnimScrollView extends ScrollView {
    // 滚动动画子视图的容器
    private ScrollAnimChildContainerLayout containerLayout;

    public MountAnimScrollView(Context context) {
        super(context);
    }

    public MountAnimScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MountAnimScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public MountAnimScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }


    // 在 LayoutInflater.from(getContext()) 中被调
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        containerLayout = (ScrollAnimChildContainerLayout) getChildAt(0);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        // 将第一个视图的高度设置为 ScrollView 的高度
        View firstChild = containerLayout.getChildAt(0);
        firstChild.getLayoutParams().height = getHeight();
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        // 滚动监听
        int scrollViewHeight = getHeight();
        int childCount = containerLayout.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = containerLayout.getChildAt(i);
            if (child instanceof ScrollAnimMountCallback) {
                dispatchAnim(child, scrollViewHeight, t);
            }
        }
    }

    /**
     * 分发动画
     *
     * @param child            子视图
     * @param scrollViewHeight ScrollView 的高度
     * @param t                当前垂直滚动原点
     */
    private void dispatchAnim(View child, int scrollViewHeight, int t) {
        ScrollAnimMountCallback scrollAnimMountCallback = (ScrollAnimMountCallback) child;
        //1.child离scrollview顶部的高度 a
        int distanceTop = child.getTop();
        int distanceHeight = child.getHeight();

        //2.得到scrollview滑出去的高度  b  就是int t,
        //3.得到child离屏幕顶部的高度  c
        int distanceAbsoluteTop = distanceTop - t;
        //什么时候执行动画？当child滑进屏幕的时候
        if (distanceAbsoluteTop <= scrollViewHeight) {
            int visibleGap = scrollViewHeight - distanceAbsoluteTop;
            //确保ratio是在0~1，超过了1 也设置为1
            scrollAnimMountCallback.onChildAnimMount(clamp(visibleGap / (float) distanceHeight, 1f, 0f));
        } else {//否则，就恢复到原来的位置
            scrollAnimMountCallback.onChildAnimUnmount();
        }
    }

    private float clamp(float value, float max, float min) {
        return Math.max(Math.min(value, max), min);
    }
}
